/**
 * Copyright © 2022 易久批信息技术有限公司. All rights reserved.
 */
package com.dysm.single;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

/**
 * 单例打破，利用反射
 * @author xiay
 * @since 2022/4/23 9:11 下午
 */
public class SingleBreakClient {

    public static void main(String[] args) throws Exception {
        // 可以通过反射进行创建实例，不满足单一原则
        Class<?> aClass = LazyManModel.class;
        Constructor<?> constructor = aClass.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object newInstance = constructor.newInstance();
        Object newInstance1 = constructor.newInstance();
        System.out.println("反射单例equals结果：" +newInstance.equals(newInstance1));


        //Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
        //	at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
        //	at com.dysm.single.SingleBreakClient.main(SingleBreakClient.java:28)
        try {
            Class<EnumModel> enumModelClass = EnumModel.class;
            Constructor<EnumModel> declaredConstructor = enumModelClass.getDeclaredConstructor(String.class, int.class);
            declaredConstructor.setAccessible(true);
            EnumModel enumModel = declaredConstructor.newInstance();
            EnumModel enumModel1 = declaredConstructor.newInstance();
            System.out.println("枚举反射单例equals结果：" + enumModel.equals(enumModel1));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 序列化测试枚举的单例原则是否被打破
        //反射单例equals结果：false
        //单例1：java.lang.Object@2f7a2457
        //单例2：java.lang.Object@2f7a2457
        //equals先序列化后反序列化对象结果：true
        //==先序列化后反序列化对象结果：true
        EnumModel instance1 = null;
        EnumModel instance2 = EnumModel.getInstance();
        instance2.setData(new Object());
        FileOutputStream fos = new FileOutputStream("EnumSingleton.obj");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(instance2);
        oos.flush();
        oos.close();
        FileInputStream fis = new FileInputStream("EnumSingleton.obj");
        ObjectInputStream ois = new ObjectInputStream(fis);
        instance1 = (EnumModel) ois.readObject();
        ois.close();
        System.out.println("单例1：" + instance1.getData());
        System.out.println("单例2：" + instance2.getData());
        System.out.println("equals先序列化后反序列化对象结果：" + instance1.getData().equals(instance2.getData()));
        System.out.println("==先序列化后反序列化对象结果：" + (instance1.getData() == instance2.getData()));

    }

}
